package widget.common.tools
{
	import flash.display.Loader;
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.SecurityDomain;
	import flash.utils.Timer;
	
	[Event(name="completeLoader" , type="widget.common.event.LoadDataEvent")]
	[Event(name="timeOutLoader" , type="widget.common.event.LoadDataEvent")]
	[Event(name="io_error", type="flash.events.IOErrorEvent")]
	[Event(name="progress", type="flash.events.ProgressEvent")]
	public class DisplayLoader extends EventDispatcher{
		
		public var loaderID : String = "";
		
		protected var loadURL : String = null;
		protected var isloading : Boolean = false;
		private var loader : Loader = null; 
		
		/**
		 * 连接次数
		 */
		private var connectNum : int = 0;
		/**
		 * 加载进度时间监听
		 */
		private var progressTimer : Timer = null;
		/**
		 * 时间计数器
		 */
		private var timerCounter : int = 0;
		/**
		 * 连接失败次数计数器
		 */
		private var failedCounter : int = 0;
		/**
		 * 重新次数连接计数器
		 */
		private var reconnectNum : int = 0;
		
		private var context:LoaderContext = null;
		public function DisplayLoader()
		{
			super(null);
		}
		
		private function configureListeners(dispatcher : IEventDispatcher) : void
		{
			dispatcher.addEventListener(Event.COMPLETE , completeHandler);
			dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS , httpStatusHandler);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR , ioErrorHandler);
			dispatcher.addEventListener(Event.OPEN , openHandler);
			dispatcher.addEventListener(ProgressEvent.PROGRESS , progressHandler);
			dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR , securityErrorHandler);
		}
		
		private function removeListeners() : void
		{
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE , completeHandler);
			loader.contentLoaderInfo.removeEventListener(HTTPStatusEvent.HTTP_STATUS , httpStatusHandler);
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR , ioErrorHandler);
			loader.contentLoaderInfo.removeEventListener(Event.OPEN , openHandler);
			loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS , progressHandler);
			loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR , securityErrorHandler);
		}
		
		protected function completeHandler(event : Event) : void{
			clearTimer();
			isloading = false;
		}
		
		private function openHandler(event : Event) : void
		{
			isloading = true;
		}
		
		private function progressHandler(event : ProgressEvent) : void
		{
			isloading = true;
			connectNum++;
			this.dispatchEvent(event);
		}
		
		private function securityErrorHandler(event : SecurityErrorEvent) : void
		{
			this.dispatchEvent(event);
			clearTimer();
			isloading = false;
		}
		
		private function httpStatusHandler(event : HTTPStatusEvent) : void
		{
			
		}
		
		private function ioErrorHandler(event : IOErrorEvent) : void
		{
			this.dispatchEvent(event);
			clearTimer();
			isloading = false;
		}
		
		/**
		 * 控制重新连接服务器
		 * @param event
		 *
		 */
		private function timerHandler(event : TimerEvent) : void
		{
			
			if (timerCounter == connectNum)
			{
				//掉线需要重新连接
				failedCounter++;
				
				if (failedCounter == 3)
				{
					failedCounter = 0;
					reconnectNum++;
					reload();
				}
				
				if (reconnectNum == 5)
				{
					//网络断掉
					clearTimer();
				}
			}
			else
			{
				timerCounter = connectNum;
			}
		}
		
		protected function clearTimer() : void
		{
			if (progressTimer)
			{
				progressTimer.stop();
				progressTimer.removeEventListener(TimerEvent.TIMER , timerHandler);
				progressTimer = null;
			}
		}
		
		protected function load(con:LoaderContext = null) : void
		{
			if(isloading){
				loader.unload();
			}
			if (loader == null)
			{
				loader = new Loader();
				configureListeners(loader.contentLoaderInfo);
			}
			else
			{
				loader.unload();
			}
			var request : URLRequest = new URLRequest(this.loadURL);
		//	var loadContext : LoaderContext = new LoaderContext(false , ApplicationDomain.currentDomain , SecurityDomain.currentDomain);
			try
			{
				context = con;
				loader.load(request,con);
			}
			catch (error : Error)
			{
				this.dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
				throw new Error("Unable to load requested URL.");
			}
			
			progressTimer = new Timer(1000);
			progressTimer.start();
			progressTimer.addEventListener(TimerEvent.TIMER , timerHandler);
		}
		
		protected function reload() : void
		{
			var request : URLRequest = new URLRequest(this.loadURL);
			try
			{
				loader.unload();
			}
			catch (e : Error)
			{
				this.dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
				throw new Error("Unable to unload connection !!!");
			}
			try
			{
				loader.load(request,context);
			}
			catch (error : IOError)
			{
				this.dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
				throw new Error("Unable to load requested file!!!");
			}
			
		}
		
		public function loadByURL(url : String):void{
			
		}
		
		public function getLoadPath():String{
			return loadURL;
		}
		
		public function clear() : void
		{
			if (loader)
			{
				removeListeners();
				loader.unload();
				loader = null;
			}
		}
	}
}